A virtual machine (VM) environment executes programs in a manner which is generally independent of the underlying complexities in the platform used to implement the execution. Microsoft Corporation's .NET Framework (provided by Microsoft Corporation of Redmond, Wash.) provides a virtual machine environment with its Common Language Runtime (CLR) functionality. Sun's Java (provided by Sun Microsystems, Inc. of Santa Clara, Calif.) provides another well known virtual machine environment.
FIG. 1 shows an overview of the operation of an exemplary architecture 100 employed by the NET Framework in generating and executing code. The architecture 100 enables a series of actions 102 used to generate intermediate language (IL) code, and another series of actions 104 for executing that intermediate language code in a specific computing platform.
To begin with, source code 106 (such as program “Application.cs”) is fed to a compiler 108. The source code can be written in a variety of languages that target the .NET Framework, such as C#, Visual Basic.NET, JScript.NET, C++ with Managed Extensions, and so on. The architecture 100 can use different kinds of compilers depending on the language used to create the source code 106. For instance, FIG. 1 shows the exemplary use of a C# compiler 108 to transform a source program written in C#.
The compiler 108 produces the intermediate language (IL) code and metadata 110. This IL is expressed in a common coding framework regardless of the language that was used to create the original source code 106. Metadata provides descriptive information regarding the IL. In general, the common coding framework provided by the IL and the metadata 110 are specifically tailored to make use of the common resources of the .NET Framework environment, and, in particular, to make use of the CLR. Code that is built to utilize the CLR is referred to as “managed code.”
A key resource provided by the CLR is its use of a common set of programming types via a Common Type System (CTS). Generally, a type pertains to rules used to interpret information in the source code. CTS specifies a variety of types, including classes, interfaces, arrays, delegates, etc. A class refers to a collection that can include methods, properties, and events. An interface also refers to a collection that can include methods, properties, and events; interfaces differ from classes in that they specify software contracts, without implementation. An array refers to a collection of values having the same type. A delegate refers to a link to a method. The above-mentioned metadata generated by the compiler 108 provides descriptive information pertaining to these types, such as the name of the type, the visibility of the type (e.g., “public” or “assembly”), the identity of any interfaces which the type references, the identity of any methods implemented by the types, and so on. Additional information regarding the basics of the .NET Framework can be found in a number of introductory texts, such as Pratt, Introducing Microsoft .NET, Third Edition, Microsoft Press, 2003.
In the execution phase 104, the architecture 100 uses a CLR loader and a just-in-time (JIT) compiler (i.e., the “loader/JIT” component) 112 to transform the IL and metadata 110 into the native code 114 specific to a particular execution platform. More specifically, the loader/JIT component 112 produces the actual machine code that will run on an execution platform (e.g., a specific computing machine). The compilation process provided by the loader/JIT component 112 is referred to as “just-in-time” because the compilation generally takes place just prior to the execution of the code.
The use of a common programming framework provided by the .NET environment (or related environments) enables diverse systems to interact with each other by sharing modules of code between themselves, and is therefore particularly advantageous in a wide-area network environment, such as the Internet. However, this modular approach can also introduce various technical challenges.
Consider, for example, the scenario shown in FIG. 2. This figure shows an exemplary interaction between a supplier 202 of software products and a customer 204 i.e., the recipient of such software products). In event 206, the supplier ships a software module referred to as LibraryOld.dll 208 to the customer. The suffix “dll” represents “dynamic linked library.” A dll typically contains a collection of data and/or executable functions that can be utilized by another program in performing specified tasks. For instance, FIG. 2 shows that the LibraryOld.dll 208 contains the definition of at least one class identified as “Aa.Bb.Cc.” As noted above, in the .NET environment, a class includes a collection of fields, methods, events, and properties. The prefix “Aa.Bb” identifies the namespace of this class. A namespace is a logical naming scheme for grouping related types. The .NET Framework uses a hierarchical naming scheme for grouping types into logical categories of related functionality.
In event 210, the customer who receives the LibraryOld.dll 208 builds a program Appln.exe 212 that utilizes the resources of the LibraryOld.dll 208. For instance, LibraryOld.dll 208 might provide a collection of data and resources that allow a customer to interact with a payroll system of a company. The Appln.exe program 212 might provide a general shell for handling various administrative tasks within the company that uses LibraryOld.dll 308 as a component part thereof. FIG. 2 specifically shows that the Appln.exe program 212 contains a reference 214 (e.g., a TypeRef reference) to the class Aa.Bb.Ca in LibraryOld.dll 208. This reference can be specified in the metadata produced by the compiler 108 shown in FIG. 1
In event 216, the supplier may modify LibraryOld.dll 208 to produce a new code module, LibrayNew.dll 218. For instance, in one case, the software module LibraryOld.dll 208 may have grown very large over successive updates, and the supplier now wishes to cull a certain collection of resources (e.g., type definitions) from the LibraryOld.dll 208 and store them in the new software module LibraryNew.dll 218. Suppose, in this example, that the supplier specifically moves the class Aa.Bb.Cc from LibraryOld.dll 208 to LibraryNew.dll 218, and then ships LibraryNew.dll 218 to the customer.
Event 220 illustrates the consequences of shipping LibraryNew.dll 218 to the customer. Namely, Appln.exe 212 still references LibraryOld.dll 208. Therefore, Appln.exe 212 will continue to interact with the resources provided by LibraryOld.dll 208, essentially ignoring any upgrade provided in LibraryNew.dll 218. The customer thereby foregoes any performance improvement provided by LibraryNew.dll 218.
To fix this problem, the customer is forced to modify the Appln.exe program 212 to ensure that it properly references LibraryNew.dll 212. This can entail a significant amount of effort, particularly in those cases involving corporations, government departments, or similar environments. These environments potentially have thousands of users, spread across many sites. The modify and rebuild operation in these environments can be time-consuming, disruptive to the environments, and may potentially introduce errors if not performed properly.
Accordingly, there is an exemplary need in the art to rectify conflicts that may arise when code resources are updated, and to address related problems that arise in analogous environments.